﻿using MvvmCross.Core.ViewModels;
using Sidvall.UI.Dialogs;
using Sidvall.UI.Entities;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Sidvall.UI.ViewModels
{
    public sealed class ProgressControlViewModel : ControlViewModelBase
    {
        #region Public Members

        public event System.EventHandler CloseSelected;

        #region MonitoredTaskItem

        private MonitoredTaskItem _MonitoredTaskItem;
        public MonitoredTaskItem MonitoredTaskItem
        {
            get
            {
                return _MonitoredTaskItem;
            }
            set
            {
                if (_MonitoredTaskItem != null)
                    _MonitoredTaskItem.PropertyChanged -= OnMonitoredTaskItemPropertyChanged;
                _MonitoredTaskItem = value;
                if (_MonitoredTaskItem != null)
                    _MonitoredTaskItem.PropertyChanged += OnMonitoredTaskItemPropertyChanged;
                RaisePropertyChanged(nameof(MonitoredTaskItem));
                RaisePropertyChanged(nameof(ActionCaption));
            }
        }

        #endregion
        #region ActionCaption

        public string ActionCaption
        {
            get
            {
                if (this.MonitoredTaskItem == null)
                    return "Close";
                switch (this.MonitoredTaskItem.Status)
                {
                    case Sidvall.Tasks.TaskStatus.Running:
                        if (this.MonitoredTaskItem.CanCancel)
                            return "Cancel";
                        else
                            return "Close";
                    default:
                        return "Close";
                }
            }
        }

        #endregion
        #region CloseWhenFinished

        private bool _CloseWhenFinished = true;
        public bool CloseWhenFinished
        {
            get
            {
                return _CloseWhenFinished;
            }
            set
            {
                _CloseWhenFinished = value;
                RaisePropertyChanged(nameof(CloseWhenFinished));
            }
        }

        #endregion
        #region CloseWhenFaulted

        private bool _CloseWhenFaulted = true;
        public bool CloseWhenFaulted
        {
            get
            {
                return _CloseWhenFaulted;
            }
            set
            {
                _CloseWhenFaulted = value;
                RaisePropertyChanged(nameof(CloseWhenFaulted));
            }
        }

        #endregion

        #region Action

        public ICommand ActionCommand
        {
            get
            {
                return new MvxCommand(async () => await ActionAsync());
            }
        }
        public Task ActionAsync()
        {
            switch (this.MonitoredTaskItem.Status)
            {
                case Sidvall.Tasks.TaskStatus.Running:
                    if (this.MonitoredTaskItem.CanCancel)
                        this.MonitoredTaskItem.Cancel();
                    else
                        OnCloseSelected();
                    break;
                default:
                    OnCloseSelected();
                    break;
            }
            return Task.FromResult(true);
        }

        #endregion
        #region Initialize

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
        public void Initialize(ProgressDialogContext context)
        {
            var item = new MonitoredTaskItem();
            item.Initialize(context);
            this.MonitoredTaskItem = item;
            if (context != null)
            {
                this.CloseWhenFaulted = context.CloseWhenFaulted;
                this.CloseWhenFinished = context.CloseWhenFinished;
            }
        }

        #endregion
        #region UnloadViewModel

        protected override void UnloadViewModel()
        {
            if (this.MonitoredTaskItem != null)
            {
                this.MonitoredTaskItem.Dispose();
                this.MonitoredTaskItem = null;
            }
            base.UnloadViewModel();
        }

        #endregion

        #endregion
        #region Private Members

        #region OnCloseSelected

        private void OnCloseSelected()
        {
            OnCloseSelected(new System.EventArgs());
        }
        private void OnCloseSelected(System.EventArgs args)
        {
            if (this.CloseSelected != null)
                this.CloseSelected.Invoke(this, args);
        }

        #endregion
        #region OnMonitoredTaskItemPropertyChanged

        private void OnMonitoredTaskItemPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            RaisePropertyChanged(nameof(ActionCaption));
        }

        #endregion

        #endregion
        #region Constructors

        public ProgressControlViewModel()
        {
        }

        #endregion
    }
}
